home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / oath.lha / oath / src / dlList.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-29  |  11.3 KB  |  517 lines

  1. //***************************************************************************
  2. //             OATH :: Object-oriented Abstract Type Hierarchy
  3. //***************************************************************************
  4. //
  5. //  Copyright (C) 1991, 1990  Texas Instruments Incorporated
  6. //  Permission is granted to any individual or institution
  7. //  to use, copy, modify, and distribute this software,
  8. //  provided that this complete copyright and permission notice
  9. //  is maintained, intact, in all copies and supporting documentation.
  10. //
  11. //  Texas Instruments Incorporated provides this software "as is"
  12. //  without express or implied warranty.
  13. //
  14. //***************************************************************************
  15. //  dlList (dlListA, dlListG)
  16. //  dlPos (dlPosA, dlPosG)
  17. //
  18. //  History:
  19. //    07/91  Brian M Kennedy  import, export, typeRegister
  20. //    06/91  Brian M Kennedy  New macros & format; remove printDiagnostic
  21. //    10/90  Brian M Kennedy  Major Rewrite
  22. //    02/90  Brian M Kennedy  Original
  23. //
  24. //***************************************************************************
  25.  
  26. #include "copyright.h"
  27.  
  28. #include <oath/dlList.h>
  29.  
  30. #include <iostream.h>
  31.  
  32. /////////////////////////////////////////////////////////////////////////////
  33. // dlList Outlines
  34.  
  35. OUTLINES(dlList, list)
  36.  
  37. // Constructors //////////
  38.  
  39.     dlListG::
  40. dlListG (int IsConst)
  41.    :listG(IsConst), Header(0), End(0), PosList(0)
  42.    {ref();
  43.        {End = Header = new dlNodeP;}
  44.     deref();
  45.    }
  46.  
  47.     dlListG::
  48. dlListG (const seqG* S, int IsConst)
  49.    :listG(IsConst), Header(0), End(0), PosList(0)
  50.    {ref();
  51.        {End = Header = new dlNodeP;
  52.     for(posA P = S->makePos(0, 0); P(); ++P)
  53.         End = End->insertAfter((*P).guts());
  54.        }
  55.     deref();
  56.    }
  57.  
  58.     dlListG::
  59. dlListG (const posG* Start, const posG* Beyond, int IsConst)
  60.    :listG(IsConst), Header(0), End(0), PosList(0)
  61.    {ref();
  62.        {End = Header = new dlNodeP;
  63.     if(Beyond->isNil())
  64.        {for(posA P = (posA&)Start->makeCopy(0); P(); ++P)
  65.             End = End->insertAfter((*P).guts());
  66.        }
  67.     else
  68.        {ensure(Start->parent()->is(Beyond->parent()), 
  69.            "The two Pos's are not from the same Seq!");
  70.         for(posA P = (posA&)Start->makeCopy(0); 
  71.                                     !Beyond->isEqual(P.guts()); ++P)
  72.            {assumed(P(), "Second Pos is not after the first!");
  73.             End = End->insertAfter((*P).guts());
  74.            }
  75.        }
  76.        }
  77.     deref();
  78.    }
  79.  
  80.     dlListG::
  81. ~dlListG ()
  82.    {ref();
  83.        {while(Header->next())
  84.         Header->deleteNext();
  85.     delete Header;
  86.        }
  87.     deref();
  88.    }
  89.  
  90.  
  91. // oathCore Operations //////////
  92.  
  93.     void dlListG::
  94. export (exportP& X) const
  95.    {X.writeType(TypeName);
  96.     int Count = count();
  97.     X.stream() << Count << (isConst() ? ' ' : '\0');
  98.     if(Count)
  99.        {for(posA P = makePos(0, 0); P(); ++P)
  100.             (*P).export(X);
  101.        }
  102.    }
  103.  
  104.     objA dlListG::
  105. import (importP& M)
  106.    {int Count;
  107.     M.stream() >> Count;
  108.     char MakeConst = M.stream().get();
  109.     if(Count)
  110.        {dlNodeP * Header = new dlNodeP;
  111.         dlNodeP * End = Header;
  112.     for(int I = 0; I < Count; ++I)
  113.            {objA Tmp = objA::import(M);
  114.         End->Next = new dlNodeP (End, 0, Tmp.guts());
  115.         End = End->Next;
  116.            }
  117.     return new dlListG (Header, End, MakeConst);
  118.        }
  119.     else
  120.         return new dlListG (MakeConst);
  121.    }
  122.  
  123.     void dlListG::
  124. clearReferences()
  125.    {clearMark();
  126.     for(dlNodeP *N = Header->next(); N; N = N->next())
  127.     N->thisObj().guts()->deref();
  128.    }
  129.  
  130.     void dlListG::
  131. setReferences()
  132.    {if(!isMarked())
  133.        {setMark();
  134.         for(dlNodeP *N = Header->next(); N; N = N->next())
  135.            {N->thisObj().guts()->ref();
  136.         N->thisObj().guts()->setReferences();
  137.        }
  138.        }
  139.    }
  140.  
  141.  
  142. // obj Operations //////////
  143.  
  144.     int dlListG::
  145. isEqual (const objG* O) const
  146.    {if(is(O))
  147.     return TRUE;
  148.     else if(!O->isImplementedAs(Type))
  149.     return FALSE;
  150.     else
  151.        {posA Pthis = makePos(0, 0);
  152.     posA PL    = ((dlListG*)O)->makePos(0, 0);
  153.     while(TRUE)
  154.        {if(Pthis.isPastEnd())
  155.         return (PL.isPastEnd() ? TRUE : FALSE);
  156.         if(PL.isPastEnd())
  157.         return FALSE;
  158.         if(!(*Pthis).is(*PL))
  159.         return FALSE;
  160.         ++Pthis;
  161.         ++PL;
  162.        }
  163.        }
  164.    }
  165.  
  166.     objA dlListG::
  167. makeCopy (int MakeConst) const
  168.    {dlNodeP * NewHead = new dlNodeP;
  169.     dlNodeP * NewEnd = NewHead;
  170.     for(dlNodeP * P = Header; P->next(); P = P->next())
  171.     NewEnd = NewEnd->insertAfter(P->nextObj().guts());
  172.     return new dlListG (NewHead, NewEnd, MakeConst);
  173.    }
  174.  
  175. // bag Operations //////////
  176.  
  177.     int dlListG::
  178. count () const
  179.    {int C = 0;
  180.     for(dlNodeP *N = Header->next(); N; N = N->next())
  181.     C++;
  182.     return C;
  183.    }
  184.  
  185.     int dlListG::
  186. contains (const objG* O) const
  187.    {for(dlNodeP *N = Header->next(); N; N = N->next())
  188.     if(O->is(N->thisObj().guts()))
  189.         return TRUE;
  190.     return FALSE;
  191.    }
  192.  
  193.     int dlListG::
  194. containsEqual (const objG* O) const
  195.    {for(dlNodeP *N = Header->next(); N; N = N->next())
  196.     if(O->isEqual(N->thisObj().guts()))
  197.         return TRUE;
  198.     return FALSE;
  199.    }
  200.  
  201.     int dlListG::
  202. canContain (const objG*) const
  203.    {return TRUE;}
  204.  
  205.     void dlListG::
  206. insert (const objG* O)
  207.    {NOT_CONST();
  208.     End = End->insertAfter(O);
  209.    }
  210.  
  211.     void dlListG::
  212. append (const bagG* B)
  213.    {NOT_CONST();
  214.     B->applyX(callSelf, this);
  215.    }
  216.  
  217.     void dlListG::
  218. apply (void (*F)(objA)) const
  219.    {for(dlNodeP *N = Header->next(); N; N = N->next())
  220.     F(N->thisObj());
  221.    }
  222.  
  223.     bagG* dlListG::
  224. applyX (objA (*F)(objA), bagG* B) const
  225.    {for(dlNodeP *N = Header->next(); N; N = N->next())
  226.        {objA O = F(N->thisObj());
  227.         B->insert(O.guts());
  228.        }
  229.     return B;
  230.    }
  231.  
  232.     bagG* dlListG::
  233. applyX (bagA (*F)(objA), bagG* B) const
  234.    {for(dlNodeP *N = Header->next(); N; N = N->next())
  235.        {bagA O = F(N->thisObj());
  236.         B->append(O.guts());
  237.        }
  238.     return B;
  239.    }
  240.  
  241.     bagA dlListG::
  242. makeEmpty () const
  243.    {return new dlListG();}
  244.  
  245.  
  246. // queue Operations //////////
  247.  
  248.     const objG* dlListG::
  249. remove ()
  250.    {NOT_CONST();
  251.     assumed(!isEmpty(), "remove() attempted on an empty Queue!");
  252.     adjustPosList(Header->next(), Header);
  253.     const objG* O = Header->nextObj().guts();
  254.     if(End == Header->next())
  255.     End = Header;
  256.     Header->deleteNext();
  257.     return O;
  258.    }
  259.  
  260.  
  261. // seq Operations //////////
  262.  
  263.     const objG* dlListG::
  264. subscript (int I) const
  265.    {dlNodeP* N = internalPosition(I);
  266.     assumed(N->next(), "Indexed beyond end of Seq!");
  267.     return N->nextObj().guts();
  268.    }
  269.  
  270.     const objG* dlListG::
  271. subscript (const posG* P) const
  272.    {ensure(!P->isNil() && is(P->parent()), "Pos not from this Sequence!");
  273.     return ((dlPosG*)P)->Prev->nextObj().guts();
  274.    }
  275.  
  276.     seqA dlListG::
  277. makeSeq (const posG* Start, const posG* Beyond, int MakeConst) const
  278.    {return new dlListG (Start, Beyond, MakeConst);}
  279.  
  280.     seqA dlListG::
  281. makeSeq (int Start, int Beyond, int MakeConst) const
  282.    {posA S = makePos(Start,TRUE);
  283.     posA B = makePos(Beyond,TRUE);
  284.     return new dlListG (S.guts(), B.guts(), MakeConst);
  285.    }
  286.  
  287.  
  288. // fifoQueue Operations //////////
  289.  
  290.  
  291. // deq Operations //////////
  292.  
  293.     void dlListG::
  294. pushFront (const objG* O)
  295.    {NOT_CONST();
  296.     Header->insertAfter(O);
  297.     if(Header == End)
  298.     End = Header->next();
  299.    }
  300.  
  301.     const objG* dlListG::
  302. pullEnd ()
  303.    {NOT_CONST();
  304.     assumed(!isEmpty(), "pullEnd() attempted on an empty Queue!");
  305.     adjustPosList(End, End->prev());
  306.     const objG* O = End->thisObj().guts();
  307.     End = End->prev();
  308.     End->deleteNext();
  309.     return O;
  310.    }
  311.  
  312.  
  313. // list Operations //////////
  314.  
  315.     void dlListG::
  316. insertList (const listPosG* P, const objG* O)
  317.    {NOT_CONST();
  318.     ensure(!P->isNil() && is(P->parent()), "Pos is not from this seq!");
  319.     ((dlPosG*)P)->Prev->insertAfter(O);
  320.     if(((dlPosG*)P)->Prev == End)
  321.     End = End->next();
  322.    }
  323.  
  324.     const objG* dlListG::
  325. removeList (const listPosG* P)
  326.    {NOT_CONST();
  327.     ensure(!P->isNil() && is(P->parent()), "Pos is not from this seq!");
  328.     dlNodeP* N = ((dlPosG*)P)->Prev->next();
  329.     assumed(N, "Attempt to delete past end with remove(P,O)!");
  330.     adjustPosList(N, ((dlPosG*)P)->Prev);
  331.     const objG* O = ((dlPosG*)P)->Prev->nextObj().guts();
  332.     if(N == End)
  333.     End = End->prev();
  334.     ((dlPosG*)P)->Prev->deleteNext();
  335.     return O;
  336.    } 
  337.  
  338.  
  339. // dlList Operations //////////
  340.  
  341.     dlNodeP * dlListG::
  342. internalPosition (int I) const
  343.    {if(!I)
  344.            return Header;
  345.     dlNodeP* N = Header;
  346.     for(int J = 0; (J < I) && N->next(); J++)
  347.     N = N->next();
  348.     return N;
  349.    }
  350.  
  351.     void dlListG::
  352. adjustPosList (dlNodeP * CurrentPrev, dlNodeP * NewPrev)
  353.    {dlPosG * Pos = PosList;
  354.     while(Pos)
  355.        {if(Pos->Prev == CurrentPrev)
  356.         Pos->Prev = NewPrev;
  357.     Pos = Pos->NextPos;
  358.        }
  359.    }
  360.  
  361.  
  362. /////////////////////////////////////////////////////////////////////////////
  363. // dlPos Outlines
  364.  
  365. OUTLINES(dlPos, listPos)
  366.  
  367. // Constructors //////////
  368.  
  369.     dlPosG::
  370. dlPosG (const dlListG* iList, dlNodeP* iPrev, int IsConst)
  371.    :listPosG(IsConst), List(iList),
  372.     Prev(iPrev), PrevPos(0), NextPos(iList->posList())
  373.    {if(NextPos)
  374.     NextPos->PrevPos = this;
  375.     List.guts()->posList() = this;
  376.    }
  377.  
  378.     dlPosG::
  379. ~dlPosG ()
  380.    {if(NextPos)
  381.     NextPos->PrevPos = PrevPos;
  382.     if(PrevPos)
  383.     PrevPos->NextPos = NextPos;
  384.     else
  385.     List.guts()->posList() = NextPos;
  386.    }
  387.  
  388. // oathCore Operations //////////
  389.  
  390.     void dlPosG::
  391. export (exportP& X) const
  392.    {X.writeType(TypeName);
  393.     List.export(X);
  394.     int I = 0;
  395.     dlPosA P = List.makePos();
  396.     while(P.guts()->Prev != Prev)
  397.        {++P; ++I;}
  398.     X.stream() << I << (isConst() ? ' ' : '\0');    
  399.    }
  400.  
  401.     objA dlPosG::
  402. import (importP& M)
  403.    {dlListA L = dlListA::isa(objA::import(M));
  404.     int I;
  405.     M.stream() >> I;
  406.     char MakeConst = M.stream().get();
  407.     return L.makePos(I, MakeConst);
  408.    }
  409.  
  410.     void dlPosG::
  411. clearReferences()
  412.    {clearMark();
  413.     List.guts()->deref();
  414.    }
  415.  
  416.     void dlPosG::
  417. setReferences()
  418.    {if(!isMarked())
  419.        {setMark();
  420.         List.guts()->ref();
  421.     List.guts()->setReferences();
  422.        }
  423.    }
  424.  
  425.  
  426. // obj Operations //////////
  427.  
  428.     int dlPosG::
  429. isEqual (const objG* O) const
  430.    {return O->isImplementedAs(Type) && (Prev == ((dlPosG*)O)->Prev);}
  431.  
  432.  
  433. // pos Operations //////////
  434.  
  435.     const objG* dlPosG::
  436. indirection () const
  437.    {assumed(Prev->next(), "Access attempted past end of Sequence");
  438.     return Prev->nextObj().guts();
  439.    }
  440.  
  441.     void dlPosG::
  442. increment ()
  443.    {NOT_CONST();
  444.     if(Prev->next())
  445.      Prev = Prev->next();
  446.    }
  447.  
  448.     void dlPosG::
  449. increment (int I)
  450.    {NOT_CONST();
  451.     for(int J = 0; (J < I) && Prev->next(); J++)
  452.     Prev = Prev->next();
  453.    }
  454.  
  455.     const objG* dlPosG::
  456. find (const objG* O)
  457.    {NOT_CONST();
  458.     dlNodeP * P = Prev;
  459.     dlNodeP * N;
  460.     while(N = P->next())
  461.        {if(O->is(N->thisObj().guts()))
  462.        {Prev = P;
  463.         return O;
  464.        }
  465.     P = N;
  466.        }
  467.     return objG::Nil;
  468.    }
  469.  
  470.     const objG* dlPosG::
  471. findEqual (const objG* O)
  472.    {NOT_CONST();
  473.     dlNodeP * P = Prev;
  474.     dlNodeP * N;
  475.     while(N = P->next())
  476.        {if(O->isEqual(N->thisObj().guts()))
  477.        {Prev = P;
  478.         return O;
  479.        }
  480.     P = N;
  481.        }
  482.     return objG::Nil;
  483.    }
  484.  
  485.     void dlPosG::
  486. reset (const posG* P)
  487.    {NOT_CONST();
  488.     ensure(P->isImplementedAs(Type) && List.is(((dlPosG*)P)->List), 
  489.        "Pos's not from same seq!");
  490.     Prev = ((dlPosG*)P)->Prev;
  491.    }
  492.  
  493.     void dlPosG::
  494. reset (int I)
  495.    {NOT_CONST();
  496.     Prev = List.guts()->internalPosition(I);
  497.    }
  498.  
  499.  
  500. // listPos Operations //////////
  501.  
  502.     void dlPosG::
  503. decrement ()
  504.    {NOT_CONST();
  505.     if(Prev->prev())
  506.     Prev = Prev->prev();
  507.    }
  508.  
  509.     void dlPosG::
  510. decrement (int I)
  511.    {NOT_CONST();
  512.     for(int J = 0; (J < I) && Prev->prev(); J++)
  513.         Prev = Prev->prev();
  514.    }
  515.  
  516. //***************************************************************************
  517.